{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Use TRPO to Play Acrobot-v1\n",
    "\n",
    "PyTorch version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import sys\n",
    "import logging\n",
    "import itertools\n",
    "\n",
    "import numpy as np\n",
    "np.random.seed(0)\n",
    "import pandas as pd\n",
    "import scipy.signal as signal\n",
    "import gym\n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "torch.manual_seed(0)\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import torch.autograd as autograd\n",
    "import torch.distributions as distributions\n",
    "\n",
    "logging.basicConfig(level=logging.DEBUG,\n",
    "        format='%(asctime)s [%(levelname)s] %(message)s',\n",
    "        stream=sys.stdout, datefmt='%H:%M:%S')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11:45:19 [INFO] env: <AcrobotEnv<Acrobot-v1>>\n",
      "11:45:19 [INFO] action_space: Discrete(3)\n",
      "11:45:19 [INFO] observation_space: Box(-28.274333953857422, 28.274333953857422, (6,), float32)\n",
      "11:45:19 [INFO] reward_range: (-inf, inf)\n",
      "11:45:19 [INFO] metadata: {'render.modes': ['human', 'rgb_array'], 'video.frames_per_second': 15}\n",
      "11:45:19 [INFO] _max_episode_steps: 500\n",
      "11:45:19 [INFO] _elapsed_steps: None\n",
      "11:45:19 [INFO] id: Acrobot-v1\n",
      "11:45:19 [INFO] entry_point: gym.envs.classic_control:AcrobotEnv\n",
      "11:45:19 [INFO] reward_threshold: -100.0\n",
      "11:45:19 [INFO] nondeterministic: False\n",
      "11:45:19 [INFO] max_episode_steps: 500\n",
      "11:45:19 [INFO] _kwargs: {}\n",
      "11:45:19 [INFO] _env_name: Acrobot\n"
     ]
    }
   ],
   "source": [
    "env = gym.make('Acrobot-v1')\n",
    "env.seed(0)\n",
    "for key in vars(env):\n",
    "    logging.info('%s: %s', key, vars(env)[key])\n",
    "for key in vars(env.spec):\n",
    "    logging.info('%s: %s', key, vars(env.spec)[key])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PPOReplayer:\n",
    "    def __init__(self):\n",
    "        self.fields = ['state', 'action', 'prob', 'advantage', 'return']\n",
    "        self.memory = pd.DataFrame(columns=self.fields)\n",
    "\n",
    "    def store(self, df):\n",
    "        self.memory = pd.concat([self.memory, df[self.fields]], ignore_index=True)\n",
    "\n",
    "    def sample(self, size):\n",
    "        indices = np.random.choice(self.memory.shape[0], size=size)\n",
    "        return (np.stack(self.memory.loc[indices, field]) for field in\n",
    "                self.fields)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def conjugate_gradient(f, b, iter_count=10, epsilon=1e-12, tol=1e-6):\n",
    "    x = b * 0.\n",
    "    r = b.clone()\n",
    "    p = b.clone()\n",
    "    rho = torch.dot(r, r)\n",
    "    for i in range(iter_count):\n",
    "        z = f(p)\n",
    "        alpha = rho / (torch.dot(p, z) + epsilon)\n",
    "        x += alpha * p\n",
    "        r -= alpha * z\n",
    "        rho_new = torch.dot(r, r)\n",
    "        p = r + (rho_new / rho) * p\n",
    "        rho = rho_new\n",
    "        if rho < tol:\n",
    "            break\n",
    "    return x, f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TRPOAgent:\n",
    "    def __init__(self, env):\n",
    "        self.gamma = 0.99\n",
    "\n",
    "        self.replayer = PPOReplayer()\n",
    "        self.trajectory = []\n",
    "\n",
    "        self.actor_net = self.build_net(\n",
    "                input_size=env.observation_space.shape[0],\n",
    "                hidden_sizes=[100,],\n",
    "                output_size=env.action_space.n, output_activator=nn.Softmax(1))\n",
    "        self.max_kl = 0.01\n",
    "        self.critic_net = self.build_net(\n",
    "                input_size=env.observation_space.shape[0],\n",
    "                hidden_sizes=[100,])\n",
    "        self.critic_optimizer = optim.Adam(self.critic_net.parameters(), 0.002)\n",
    "        self.critic_loss = nn.MSELoss()\n",
    "\n",
    "    def build_net(self, input_size, hidden_sizes, output_size=1,\n",
    "            output_activator=None):\n",
    "        layers = []\n",
    "        for input_size, output_size in zip(\n",
    "                [input_size,] + hidden_sizes, hidden_sizes + [output_size,]):\n",
    "            layers.append(nn.Linear(input_size, output_size))\n",
    "            layers.append(nn.ReLU())\n",
    "        layers = layers[:-1]\n",
    "        if output_activator:\n",
    "            layers.append(output_activator)\n",
    "        net = nn.Sequential(*layers)\n",
    "        return net\n",
    "\n",
    "    def reset(self, mode=None):\n",
    "        self.mode = mode\n",
    "        if self.mode == 'train':\n",
    "            self.trajectory = []\n",
    "\n",
    "    def step(self, observation, reward, done):\n",
    "        state_tensor = torch.as_tensor(observation, dtype=torch.float).unsqueeze(0)\n",
    "        prob_tensor = self.actor_net(state_tensor)\n",
    "        action_tensor = distributions.Categorical(prob_tensor).sample()\n",
    "        action = action_tensor.numpy()[0]\n",
    "        if self.mode == 'train':\n",
    "            self.trajectory += [observation, reward, done, action]\n",
    "        return action\n",
    "\n",
    "    def close(self):\n",
    "        if self.mode == 'train':\n",
    "            self.save_trajectory_to_replayer()\n",
    "            if len(self.replayer.memory) >= 1000:\n",
    "                for batch in range(5): # learn multiple times\n",
    "                    self.learn()\n",
    "                self.replayer = PPOReplayer() # reset replayer after the agent changes itself\n",
    "\n",
    "    def save_trajectory_to_replayer(self):\n",
    "        df = pd.DataFrame(\n",
    "                np.array(self.trajectory, dtype=object).reshape(-1, 4),\n",
    "                columns=['state', 'reward', 'done', 'action'])\n",
    "        state_tensor = torch.as_tensor(np.stack(df['state']), dtype=torch.float)\n",
    "        action_tensor = torch.as_tensor(df['action'], dtype=torch.long)\n",
    "        v_tensor = self.critic_net(state_tensor)\n",
    "        df['v'] = v_tensor.detach().numpy()\n",
    "        prob_tensor = self.actor_net(state_tensor)\n",
    "        pi_tensor = prob_tensor.gather(-1, action_tensor.unsqueeze(1)).squeeze(1)\n",
    "        df['prob'] = pi_tensor.detach().numpy()\n",
    "        df['next_v'] = df['v'].shift(-1).fillna(0.)\n",
    "        df['u'] = df['reward'] + self.gamma * df['next_v']\n",
    "        df['delta'] = df['u'] - df['v']\n",
    "        df['advantage'] = signal.lfilter([1.,], [1., -self.gamma],\n",
    "                df['delta'][::-1])[::-1]\n",
    "        df['return'] = signal.lfilter([1.,], [1., -self.gamma],\n",
    "                df['reward'][::-1])[::-1]\n",
    "        self.replayer.store(df)\n",
    "\n",
    "    def learn(self):\n",
    "        states, actions, old_pis, advantages, returns = \\\n",
    "                self.replayer.sample(size=64)\n",
    "        state_tensor = torch.as_tensor(states, dtype=torch.float)\n",
    "        action_tensor = torch.as_tensor(actions, dtype=torch.long)\n",
    "        old_pi_tensor = torch.as_tensor(old_pis, dtype=torch.float)\n",
    "        advantage_tensor = torch.as_tensor(advantages, dtype=torch.float)\n",
    "        return_tensor = torch.as_tensor(returns, dtype=torch.float).unsqueeze(1)\n",
    "\n",
    "        # train actor\n",
    "        # ... calculate first order gradient: g\n",
    "        all_pi_tensor = self.actor_net(state_tensor)\n",
    "        pi_tensor = all_pi_tensor.gather(1, action_tensor.unsqueeze(1)).squeeze(1)\n",
    "        surrogate_tensor = (pi_tensor / old_pi_tensor) * advantage_tensor\n",
    "        loss_tensor = surrogate_tensor.mean()\n",
    "        loss_grads = autograd.grad(loss_tensor, self.actor_net.parameters())\n",
    "        loss_grad = torch.cat([grad.view(-1) for grad in loss_grads]).detach()\n",
    "                # flatten for calculating conjugate gradient\n",
    "\n",
    "        # ... calculate conjugate gradient: Fx = g\n",
    "        def f(x): # calculate Fx\n",
    "            prob_tensor = self.actor_net(state_tensor)\n",
    "            prob_old_tensor = prob_tensor.detach()\n",
    "            kld_tensor = (prob_old_tensor * torch.log(\n",
    "                    (prob_old_tensor / prob_tensor).clamp(1e-6, 1e6))).sum(axis=1)\n",
    "            kld_loss_tensor = kld_tensor.mean()\n",
    "            grads = autograd.grad(kld_loss_tensor, self.actor_net.parameters(), create_graph=True)\n",
    "            flatten_grad_tensor = torch.cat([grad.view(-1) for grad in grads])\n",
    "            grad_matmul_x = torch.dot(flatten_grad_tensor, x)\n",
    "            grad_grads = autograd.grad(grad_matmul_x, self.actor_net.parameters())\n",
    "            flatten_grad_grad = torch.cat([grad.contiguous().view(-1) for grad in grad_grads]).detach()\n",
    "            fx = flatten_grad_grad + x * 0.01\n",
    "            return fx\n",
    "        x, fx = conjugate_gradient(f, loss_grad)\n",
    "\n",
    "        # ... calculate natural gradient: sqrt(...) g\n",
    "        natural_gradient_tensor = torch.sqrt(2 * self.max_kl / torch.dot(fx, x)) * x\n",
    "\n",
    "        # ... line search\n",
    "        def set_actor_net_params(flatten_params):\n",
    "                # auxiliary function to overwrite actor_net\n",
    "            begin = 0\n",
    "            for param in self.actor_net.parameters():\n",
    "                end = begin + param.numel()\n",
    "                param.data.copy_(flatten_params[begin:end].view(param.size()))\n",
    "                begin = end\n",
    "\n",
    "        old_param = torch.cat([param.view(-1) for param in self.actor_net.parameters()])\n",
    "        expected_improve = torch.dot(loss_grad, natural_gradient_tensor)\n",
    "        for learning_step in [0.,] + [.5 ** j for j in range(10)]:\n",
    "            new_param = old_param + learning_step * natural_gradient_tensor\n",
    "            set_actor_net_params(new_param)\n",
    "            all_pi_tensor = self.actor_net(state_tensor)\n",
    "            new_pi_tensor = all_pi_tensor.gather(1, action_tensor.unsqueeze(1)).squeeze(1)\n",
    "            new_pi_tensor = new_pi_tensor.detach()\n",
    "            surrogate_tensor = (new_pi_tensor / pi_tensor) * advantage_tensor\n",
    "            objective = surrogate_tensor.mean().item()\n",
    "            if np.isclose(learning_step, 0.):\n",
    "                old_objective = objective\n",
    "            else:\n",
    "                if objective - old_objective > 0.1 * expected_improve * learning_step:\n",
    "                    break # success, keep the weight\n",
    "        else:\n",
    "            set_actor_net_params(old_param)\n",
    "\n",
    "        # train critic\n",
    "        pred_tensor = self.critic_net(state_tensor)\n",
    "        critic_loss_tensor = self.critic_loss(pred_tensor, return_tensor)\n",
    "        self.critic_optimizer.zero_grad()\n",
    "        critic_loss_tensor.backward()\n",
    "        self.critic_optimizer.step()\n",
    "\n",
    "\n",
    "agent = TRPOAgent(env)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11:45:19 [INFO] ==== train ====\n",
      "11:45:19 [INFO] NumExpr defaulting to 8 threads.\n",
      "11:45:19 [DEBUG] train episode 0: reward = -500.00, steps = 500\n",
      "11:45:20 [DEBUG] train episode 1: reward = -500.00, steps = 500\n",
      "11:45:20 [DEBUG] train episode 2: reward = -500.00, steps = 500\n",
      "11:45:21 [DEBUG] train episode 3: reward = -500.00, steps = 500\n",
      "11:45:21 [DEBUG] train episode 4: reward = -500.00, steps = 500\n",
      "11:45:22 [DEBUG] train episode 5: reward = -500.00, steps = 500\n",
      "11:45:22 [DEBUG] train episode 6: reward = -371.00, steps = 372\n",
      "11:45:23 [DEBUG] train episode 7: reward = -344.00, steps = 345\n",
      "11:45:23 [DEBUG] train episode 8: reward = -311.00, steps = 312\n",
      "11:45:23 [DEBUG] train episode 9: reward = -286.00, steps = 287\n",
      "11:45:24 [DEBUG] train episode 10: reward = -398.00, steps = 399\n",
      "11:45:24 [DEBUG] train episode 11: reward = -282.00, steps = 283\n",
      "11:45:25 [DEBUG] train episode 12: reward = -454.00, steps = 455\n",
      "11:45:25 [DEBUG] train episode 13: reward = -467.00, steps = 468\n",
      "11:45:25 [DEBUG] train episode 14: reward = -500.00, steps = 500\n",
      "11:45:26 [DEBUG] train episode 15: reward = -369.00, steps = 370\n",
      "11:45:26 [DEBUG] train episode 16: reward = -468.00, steps = 469\n",
      "11:45:27 [DEBUG] train episode 17: reward = -483.00, steps = 484\n",
      "11:45:27 [DEBUG] train episode 18: reward = -366.00, steps = 367\n",
      "11:45:27 [DEBUG] train episode 19: reward = -447.00, steps = 448\n",
      "11:45:28 [DEBUG] train episode 20: reward = -500.00, steps = 500\n",
      "11:45:28 [DEBUG] train episode 21: reward = -330.00, steps = 331\n",
      "11:45:29 [DEBUG] train episode 22: reward = -500.00, steps = 500\n",
      "11:45:29 [DEBUG] train episode 23: reward = -500.00, steps = 500\n",
      "11:45:30 [DEBUG] train episode 24: reward = -500.00, steps = 500\n",
      "11:45:30 [DEBUG] train episode 25: reward = -274.00, steps = 275\n",
      "11:45:30 [DEBUG] train episode 26: reward = -413.00, steps = 414\n",
      "11:45:30 [DEBUG] train episode 27: reward = -232.00, steps = 233\n",
      "11:45:31 [DEBUG] train episode 28: reward = -320.00, steps = 321\n",
      "11:45:31 [DEBUG] train episode 29: reward = -233.00, steps = 234\n",
      "11:45:31 [DEBUG] train episode 30: reward = -183.00, steps = 184\n",
      "11:45:32 [DEBUG] train episode 31: reward = -380.00, steps = 381\n",
      "11:45:32 [DEBUG] train episode 32: reward = -489.00, steps = 490\n",
      "11:45:32 [DEBUG] train episode 33: reward = -500.00, steps = 500\n",
      "11:45:33 [DEBUG] train episode 34: reward = -352.00, steps = 353\n",
      "11:45:33 [DEBUG] train episode 35: reward = -333.00, steps = 334\n",
      "11:45:33 [DEBUG] train episode 36: reward = -244.00, steps = 245\n",
      "11:45:34 [DEBUG] train episode 37: reward = -271.00, steps = 272\n",
      "11:45:34 [DEBUG] train episode 38: reward = -243.00, steps = 244\n",
      "11:45:34 [DEBUG] train episode 39: reward = -368.00, steps = 369\n",
      "11:45:35 [DEBUG] train episode 40: reward = -312.00, steps = 313\n",
      "11:45:35 [DEBUG] train episode 41: reward = -487.00, steps = 488\n",
      "11:45:35 [DEBUG] train episode 42: reward = -289.00, steps = 290\n",
      "11:45:36 [DEBUG] train episode 43: reward = -341.00, steps = 342\n",
      "11:45:36 [DEBUG] train episode 44: reward = -241.00, steps = 242\n",
      "11:45:36 [DEBUG] train episode 45: reward = -289.00, steps = 290\n",
      "11:45:37 [DEBUG] train episode 46: reward = -500.00, steps = 500\n",
      "11:45:37 [DEBUG] train episode 47: reward = -500.00, steps = 500\n",
      "11:45:38 [DEBUG] train episode 48: reward = -139.00, steps = 140\n",
      "11:45:38 [DEBUG] train episode 49: reward = -215.00, steps = 216\n",
      "11:45:38 [DEBUG] train episode 50: reward = -154.00, steps = 155\n",
      "11:45:38 [DEBUG] train episode 51: reward = -111.00, steps = 112\n",
      "11:45:38 [DEBUG] train episode 52: reward = -139.00, steps = 140\n",
      "11:45:38 [DEBUG] train episode 53: reward = -138.00, steps = 139\n",
      "11:45:39 [DEBUG] train episode 54: reward = -136.00, steps = 137\n",
      "11:45:39 [DEBUG] train episode 55: reward = -248.00, steps = 249\n",
      "11:45:39 [DEBUG] train episode 56: reward = -150.00, steps = 151\n",
      "11:45:39 [DEBUG] train episode 57: reward = -298.00, steps = 299\n",
      "11:45:39 [DEBUG] train episode 58: reward = -258.00, steps = 259\n",
      "11:45:40 [DEBUG] train episode 59: reward = -232.00, steps = 233\n",
      "11:45:40 [DEBUG] train episode 60: reward = -500.00, steps = 500\n",
      "11:45:40 [DEBUG] train episode 61: reward = -362.00, steps = 363\n",
      "11:45:41 [DEBUG] train episode 62: reward = -304.00, steps = 305\n",
      "11:45:41 [DEBUG] train episode 63: reward = -380.00, steps = 381\n",
      "11:45:41 [DEBUG] train episode 64: reward = -269.00, steps = 270\n",
      "11:45:42 [DEBUG] train episode 65: reward = -234.00, steps = 235\n",
      "11:45:42 [DEBUG] train episode 66: reward = -334.00, steps = 335\n",
      "11:45:42 [DEBUG] train episode 67: reward = -180.00, steps = 181\n",
      "11:45:42 [DEBUG] train episode 68: reward = -222.00, steps = 223\n",
      "11:45:43 [DEBUG] train episode 69: reward = -195.00, steps = 196\n",
      "11:45:43 [DEBUG] train episode 70: reward = -363.00, steps = 364\n",
      "11:45:43 [DEBUG] train episode 71: reward = -172.00, steps = 173\n",
      "11:45:44 [DEBUG] train episode 72: reward = -500.00, steps = 500\n",
      "11:45:44 [DEBUG] train episode 73: reward = -500.00, steps = 500\n",
      "11:45:45 [DEBUG] train episode 74: reward = -500.00, steps = 500\n",
      "11:45:45 [DEBUG] train episode 75: reward = -500.00, steps = 500\n",
      "11:45:46 [DEBUG] train episode 76: reward = -500.00, steps = 500\n",
      "11:45:46 [DEBUG] train episode 77: reward = -500.00, steps = 500\n",
      "11:45:47 [DEBUG] train episode 78: reward = -366.00, steps = 367\n",
      "11:45:47 [DEBUG] train episode 79: reward = -344.00, steps = 345\n",
      "11:45:48 [DEBUG] train episode 80: reward = -500.00, steps = 500\n",
      "11:45:48 [DEBUG] train episode 81: reward = -172.00, steps = 173\n",
      "11:45:48 [DEBUG] train episode 82: reward = -159.00, steps = 160\n",
      "11:45:48 [DEBUG] train episode 83: reward = -255.00, steps = 256\n",
      "11:45:48 [DEBUG] train episode 84: reward = -160.00, steps = 161\n",
      "11:45:48 [DEBUG] train episode 85: reward = -162.00, steps = 163\n",
      "11:45:49 [DEBUG] train episode 86: reward = -294.00, steps = 295\n",
      "11:45:49 [DEBUG] train episode 87: reward = -222.00, steps = 223\n",
      "11:45:49 [DEBUG] train episode 88: reward = -155.00, steps = 156\n",
      "11:45:49 [DEBUG] train episode 89: reward = -172.00, steps = 173\n",
      "11:45:49 [DEBUG] train episode 90: reward = -134.00, steps = 135\n",
      "11:45:50 [DEBUG] train episode 91: reward = -159.00, steps = 160\n",
      "11:45:50 [DEBUG] train episode 92: reward = -128.00, steps = 129\n",
      "11:45:50 [DEBUG] train episode 93: reward = -147.00, steps = 148\n",
      "11:45:50 [DEBUG] train episode 94: reward = -194.00, steps = 195\n",
      "11:45:50 [DEBUG] train episode 95: reward = -155.00, steps = 156\n",
      "11:45:50 [DEBUG] train episode 96: reward = -173.00, steps = 174\n",
      "11:45:51 [DEBUG] train episode 97: reward = -192.00, steps = 193\n",
      "11:45:51 [DEBUG] train episode 98: reward = -165.00, steps = 166\n",
      "11:45:51 [DEBUG] train episode 99: reward = -182.00, steps = 183\n",
      "11:45:51 [DEBUG] train episode 100: reward = -252.00, steps = 253\n",
      "11:45:51 [DEBUG] train episode 101: reward = -157.00, steps = 158\n",
      "11:45:52 [DEBUG] train episode 102: reward = -172.00, steps = 173\n",
      "11:45:52 [DEBUG] train episode 103: reward = -176.00, steps = 177\n",
      "11:45:52 [DEBUG] train episode 104: reward = -231.00, steps = 232\n",
      "11:45:52 [DEBUG] train episode 105: reward = -209.00, steps = 210\n",
      "11:45:52 [DEBUG] train episode 106: reward = -171.00, steps = 172\n",
      "11:45:53 [DEBUG] train episode 107: reward = -159.00, steps = 160\n",
      "11:45:53 [DEBUG] train episode 108: reward = -238.00, steps = 239\n",
      "11:45:53 [DEBUG] train episode 109: reward = -152.00, steps = 153\n",
      "11:45:53 [DEBUG] train episode 110: reward = -226.00, steps = 227\n",
      "11:45:53 [DEBUG] train episode 111: reward = -210.00, steps = 211\n",
      "11:45:54 [DEBUG] train episode 112: reward = -382.00, steps = 383\n",
      "11:45:54 [DEBUG] train episode 113: reward = -205.00, steps = 206\n",
      "11:45:54 [DEBUG] train episode 114: reward = -230.00, steps = 231\n",
      "11:45:55 [DEBUG] train episode 115: reward = -311.00, steps = 312\n",
      "11:45:55 [DEBUG] train episode 116: reward = -281.00, steps = 282\n",
      "11:45:55 [DEBUG] train episode 117: reward = -310.00, steps = 311\n",
      "11:45:55 [DEBUG] train episode 118: reward = -199.00, steps = 200\n",
      "11:45:55 [DEBUG] train episode 119: reward = -178.00, steps = 179\n",
      "11:45:56 [DEBUG] train episode 120: reward = -236.00, steps = 237\n",
      "11:45:56 [DEBUG] train episode 121: reward = -206.00, steps = 207\n",
      "11:45:56 [DEBUG] train episode 122: reward = -220.00, steps = 221\n",
      "11:45:56 [DEBUG] train episode 123: reward = -195.00, steps = 196\n",
      "11:45:56 [DEBUG] train episode 124: reward = -171.00, steps = 172\n",
      "11:45:57 [DEBUG] train episode 125: reward = -246.00, steps = 247\n",
      "11:45:57 [DEBUG] train episode 126: reward = -200.00, steps = 201\n",
      "11:45:57 [DEBUG] train episode 127: reward = -163.00, steps = 164\n",
      "11:45:57 [DEBUG] train episode 128: reward = -206.00, steps = 207\n",
      "11:45:58 [DEBUG] train episode 129: reward = -177.00, steps = 178\n",
      "11:45:58 [DEBUG] train episode 130: reward = -232.00, steps = 233\n",
      "11:45:58 [DEBUG] train episode 131: reward = -151.00, steps = 152\n",
      "11:45:58 [DEBUG] train episode 132: reward = -288.00, steps = 289\n",
      "11:45:59 [DEBUG] train episode 133: reward = -301.00, steps = 302\n",
      "11:45:59 [DEBUG] train episode 134: reward = -416.00, steps = 417\n",
      "11:45:59 [DEBUG] train episode 135: reward = -304.00, steps = 305\n",
      "11:46:00 [DEBUG] train episode 136: reward = -500.00, steps = 500\n",
      "11:46:00 [DEBUG] train episode 137: reward = -370.00, steps = 371\n",
      "11:46:01 [DEBUG] train episode 138: reward = -456.00, steps = 457\n",
      "11:46:01 [DEBUG] train episode 139: reward = -237.00, steps = 238\n",
      "11:46:01 [DEBUG] train episode 140: reward = -359.00, steps = 360\n",
      "11:46:01 [DEBUG] train episode 141: reward = -227.00, steps = 228\n",
      "11:46:02 [DEBUG] train episode 142: reward = -454.00, steps = 455\n",
      "11:46:02 [DEBUG] train episode 143: reward = -293.00, steps = 294\n",
      "11:46:03 [DEBUG] train episode 144: reward = -337.00, steps = 338\n",
      "11:46:03 [DEBUG] train episode 145: reward = -246.00, steps = 247\n",
      "11:46:03 [DEBUG] train episode 146: reward = -241.00, steps = 242\n",
      "11:46:03 [DEBUG] train episode 147: reward = -294.00, steps = 295\n",
      "11:46:04 [DEBUG] train episode 148: reward = -303.00, steps = 304\n",
      "11:46:04 [DEBUG] train episode 149: reward = -211.00, steps = 212\n",
      "11:46:04 [DEBUG] train episode 150: reward = -191.00, steps = 192\n",
      "11:46:04 [DEBUG] train episode 151: reward = -180.00, steps = 181\n",
      "11:46:04 [DEBUG] train episode 152: reward = -233.00, steps = 234\n",
      "11:46:05 [DEBUG] train episode 153: reward = -282.00, steps = 283\n",
      "11:46:05 [DEBUG] train episode 154: reward = -283.00, steps = 284\n",
      "11:46:05 [DEBUG] train episode 155: reward = -255.00, steps = 256\n",
      "11:46:06 [DEBUG] train episode 156: reward = -356.00, steps = 357\n",
      "11:46:06 [DEBUG] train episode 157: reward = -203.00, steps = 204\n",
      "11:46:06 [DEBUG] train episode 158: reward = -270.00, steps = 271\n",
      "11:46:06 [DEBUG] train episode 159: reward = -361.00, steps = 362\n",
      "11:46:07 [DEBUG] train episode 160: reward = -267.00, steps = 268\n",
      "11:46:07 [DEBUG] train episode 161: reward = -232.00, steps = 233\n",
      "11:46:07 [DEBUG] train episode 162: reward = -186.00, steps = 187\n",
      "11:46:07 [DEBUG] train episode 163: reward = -178.00, steps = 179\n",
      "11:46:08 [DEBUG] train episode 164: reward = -201.00, steps = 202\n",
      "11:46:08 [DEBUG] train episode 165: reward = -253.00, steps = 254\n",
      "11:46:08 [DEBUG] train episode 166: reward = -196.00, steps = 197\n",
      "11:46:09 [DEBUG] train episode 167: reward = -419.00, steps = 420\n",
      "11:46:09 [DEBUG] train episode 168: reward = -208.00, steps = 209\n",
      "11:46:09 [DEBUG] train episode 169: reward = -277.00, steps = 278\n",
      "11:46:09 [DEBUG] train episode 170: reward = -304.00, steps = 305\n",
      "11:46:10 [DEBUG] train episode 171: reward = -224.00, steps = 225\n",
      "11:46:10 [DEBUG] train episode 172: reward = -282.00, steps = 283\n",
      "11:46:10 [DEBUG] train episode 173: reward = -296.00, steps = 297\n",
      "11:46:10 [DEBUG] train episode 174: reward = -211.00, steps = 212\n",
      "11:46:11 [DEBUG] train episode 175: reward = -216.00, steps = 217\n",
      "11:46:11 [DEBUG] train episode 176: reward = -192.00, steps = 193\n",
      "11:46:11 [DEBUG] train episode 177: reward = -248.00, steps = 249\n",
      "11:46:12 [DEBUG] train episode 178: reward = -409.00, steps = 410\n",
      "11:46:12 [DEBUG] train episode 179: reward = -231.00, steps = 232\n",
      "11:46:12 [DEBUG] train episode 180: reward = -171.00, steps = 172\n",
      "11:46:12 [DEBUG] train episode 181: reward = -209.00, steps = 210\n",
      "11:46:12 [DEBUG] train episode 182: reward = -147.00, steps = 148\n",
      "11:46:12 [DEBUG] train episode 183: reward = -217.00, steps = 218\n",
      "11:46:13 [DEBUG] train episode 184: reward = -218.00, steps = 219\n",
      "11:46:13 [DEBUG] train episode 185: reward = -214.00, steps = 215\n",
      "11:46:13 [DEBUG] train episode 186: reward = -236.00, steps = 237\n",
      "11:46:13 [DEBUG] train episode 187: reward = -236.00, steps = 237\n",
      "11:46:14 [DEBUG] train episode 188: reward = -236.00, steps = 237\n",
      "11:46:14 [DEBUG] train episode 189: reward = -203.00, steps = 204\n",
      "11:46:14 [DEBUG] train episode 190: reward = -162.00, steps = 163\n",
      "11:46:14 [DEBUG] train episode 191: reward = -180.00, steps = 181\n",
      "11:46:14 [DEBUG] train episode 192: reward = -190.00, steps = 191\n",
      "11:46:14 [DEBUG] train episode 193: reward = -168.00, steps = 169\n",
      "11:46:15 [DEBUG] train episode 194: reward = -258.00, steps = 259\n",
      "11:46:15 [DEBUG] train episode 195: reward = -179.00, steps = 180\n",
      "11:46:15 [DEBUG] train episode 196: reward = -169.00, steps = 170\n",
      "11:46:15 [DEBUG] train episode 197: reward = -147.00, steps = 148\n",
      "11:46:15 [DEBUG] train episode 198: reward = -167.00, steps = 168\n",
      "11:46:16 [DEBUG] train episode 199: reward = -226.00, steps = 227\n",
      "11:46:16 [DEBUG] train episode 200: reward = -158.00, steps = 159\n",
      "11:46:16 [DEBUG] train episode 201: reward = -137.00, steps = 138\n",
      "11:46:16 [DEBUG] train episode 202: reward = -177.00, steps = 178\n",
      "11:46:16 [DEBUG] train episode 203: reward = -126.00, steps = 127\n",
      "11:46:17 [DEBUG] train episode 204: reward = -150.00, steps = 151\n",
      "11:46:17 [DEBUG] train episode 205: reward = -132.00, steps = 133\n",
      "11:46:17 [DEBUG] train episode 206: reward = -175.00, steps = 176\n",
      "11:46:17 [DEBUG] train episode 207: reward = -171.00, steps = 172\n",
      "11:46:17 [DEBUG] train episode 208: reward = -147.00, steps = 148\n",
      "11:46:17 [DEBUG] train episode 209: reward = -160.00, steps = 161\n",
      "11:46:18 [DEBUG] train episode 210: reward = -176.00, steps = 177\n",
      "11:46:18 [DEBUG] train episode 211: reward = -153.00, steps = 154\n",
      "11:46:18 [DEBUG] train episode 212: reward = -136.00, steps = 137\n",
      "11:46:18 [DEBUG] train episode 213: reward = -150.00, steps = 151\n",
      "11:46:18 [DEBUG] train episode 214: reward = -138.00, steps = 139\n",
      "11:46:18 [DEBUG] train episode 215: reward = -137.00, steps = 138\n",
      "11:46:19 [DEBUG] train episode 216: reward = -119.00, steps = 120\n",
      "11:46:19 [DEBUG] train episode 217: reward = -127.00, steps = 128\n",
      "11:46:19 [DEBUG] train episode 218: reward = -124.00, steps = 125\n",
      "11:46:19 [DEBUG] train episode 219: reward = -164.00, steps = 165\n",
      "11:46:19 [DEBUG] train episode 220: reward = -138.00, steps = 139\n",
      "11:46:19 [DEBUG] train episode 221: reward = -136.00, steps = 137\n",
      "11:46:19 [DEBUG] train episode 222: reward = -106.00, steps = 107\n",
      "11:46:20 [DEBUG] train episode 223: reward = -116.00, steps = 117\n",
      "11:46:20 [DEBUG] train episode 224: reward = -123.00, steps = 124\n",
      "11:46:20 [DEBUG] train episode 225: reward = -128.00, steps = 129\n",
      "11:46:20 [DEBUG] train episode 226: reward = -116.00, steps = 117\n",
      "11:46:20 [DEBUG] train episode 227: reward = -145.00, steps = 146\n",
      "11:46:20 [DEBUG] train episode 228: reward = -160.00, steps = 161\n",
      "11:46:20 [DEBUG] train episode 229: reward = -131.00, steps = 132\n",
      "11:46:21 [DEBUG] train episode 230: reward = -138.00, steps = 139\n",
      "11:46:21 [DEBUG] train episode 231: reward = -104.00, steps = 105\n",
      "11:46:21 [DEBUG] train episode 232: reward = -118.00, steps = 119\n",
      "11:46:21 [DEBUG] train episode 233: reward = -103.00, steps = 104\n",
      "11:46:21 [DEBUG] train episode 234: reward = -112.00, steps = 113\n",
      "11:46:21 [DEBUG] train episode 235: reward = -124.00, steps = 125\n",
      "11:46:21 [DEBUG] train episode 236: reward = -141.00, steps = 142\n",
      "11:46:22 [DEBUG] train episode 237: reward = -141.00, steps = 142\n",
      "11:46:22 [DEBUG] train episode 238: reward = -141.00, steps = 142\n",
      "11:46:22 [DEBUG] train episode 239: reward = -127.00, steps = 128\n",
      "11:46:22 [DEBUG] train episode 240: reward = -151.00, steps = 152\n",
      "11:46:22 [DEBUG] train episode 241: reward = -107.00, steps = 108\n",
      "11:46:22 [DEBUG] train episode 242: reward = -107.00, steps = 108\n",
      "11:46:22 [DEBUG] train episode 243: reward = -131.00, steps = 132\n",
      "11:46:23 [DEBUG] train episode 244: reward = -113.00, steps = 114\n",
      "11:46:23 [DEBUG] train episode 245: reward = -140.00, steps = 141\n",
      "11:46:23 [DEBUG] train episode 246: reward = -124.00, steps = 125\n",
      "11:46:23 [DEBUG] train episode 247: reward = -143.00, steps = 144\n",
      "11:46:23 [DEBUG] train episode 248: reward = -123.00, steps = 124\n",
      "11:46:23 [DEBUG] train episode 249: reward = -126.00, steps = 127\n",
      "11:46:23 [DEBUG] train episode 250: reward = -109.00, steps = 110\n",
      "11:46:24 [DEBUG] train episode 251: reward = -117.00, steps = 118\n",
      "11:46:24 [DEBUG] train episode 252: reward = -111.00, steps = 112\n",
      "11:46:24 [DEBUG] train episode 253: reward = -124.00, steps = 125\n",
      "11:46:24 [DEBUG] train episode 254: reward = -115.00, steps = 116\n",
      "11:46:24 [DEBUG] train episode 255: reward = -106.00, steps = 107\n",
      "11:46:24 [INFO] ==== test ====\n",
      "11:46:24 [DEBUG] test episode 0: reward = -100.00, steps = 101\n",
      "11:46:24 [DEBUG] test episode 1: reward = -108.00, steps = 109\n",
      "11:46:24 [DEBUG] test episode 2: reward = -192.00, steps = 193\n",
      "11:46:24 [DEBUG] test episode 3: reward = -128.00, steps = 129\n",
      "11:46:25 [DEBUG] test episode 4: reward = -139.00, steps = 140\n",
      "11:46:25 [DEBUG] test episode 5: reward = -110.00, steps = 111\n",
      "11:46:25 [DEBUG] test episode 6: reward = -119.00, steps = 120\n",
      "11:46:25 [DEBUG] test episode 7: reward = -124.00, steps = 125\n",
      "11:46:25 [DEBUG] test episode 8: reward = -155.00, steps = 156\n",
      "11:46:25 [DEBUG] test episode 9: reward = -124.00, steps = 125\n",
      "11:46:25 [DEBUG] test episode 10: reward = -129.00, steps = 130\n",
      "11:46:25 [DEBUG] test episode 11: reward = -127.00, steps = 128\n",
      "11:46:26 [DEBUG] test episode 12: reward = -124.00, steps = 125\n",
      "11:46:26 [DEBUG] test episode 13: reward = -135.00, steps = 136\n",
      "11:46:26 [DEBUG] test episode 14: reward = -118.00, steps = 119\n",
      "11:46:26 [DEBUG] test episode 15: reward = -150.00, steps = 151\n",
      "11:46:26 [DEBUG] test episode 16: reward = -141.00, steps = 142\n",
      "11:46:26 [DEBUG] test episode 17: reward = -114.00, steps = 115\n",
      "11:46:26 [DEBUG] test episode 18: reward = -112.00, steps = 113\n",
      "11:46:26 [DEBUG] test episode 19: reward = -126.00, steps = 127\n",
      "11:46:27 [DEBUG] test episode 20: reward = -129.00, steps = 130\n",
      "11:46:27 [DEBUG] test episode 21: reward = -106.00, steps = 107\n",
      "11:46:27 [DEBUG] test episode 22: reward = -194.00, steps = 195\n",
      "11:46:27 [DEBUG] test episode 23: reward = -114.00, steps = 115\n",
      "11:46:27 [DEBUG] test episode 24: reward = -106.00, steps = 107\n",
      "11:46:27 [DEBUG] test episode 25: reward = -110.00, steps = 111\n",
      "11:46:27 [DEBUG] test episode 26: reward = -136.00, steps = 137\n",
      "11:46:27 [DEBUG] test episode 27: reward = -140.00, steps = 141\n",
      "11:46:27 [DEBUG] test episode 28: reward = -104.00, steps = 105\n",
      "11:46:27 [DEBUG] test episode 29: reward = -103.00, steps = 104\n",
      "11:46:28 [DEBUG] test episode 30: reward = -123.00, steps = 124\n",
      "11:46:28 [DEBUG] test episode 31: reward = -119.00, steps = 120\n",
      "11:46:28 [DEBUG] test episode 32: reward = -131.00, steps = 132\n",
      "11:46:28 [DEBUG] test episode 33: reward = -130.00, steps = 131\n",
      "11:46:28 [DEBUG] test episode 34: reward = -143.00, steps = 144\n",
      "11:46:28 [DEBUG] test episode 35: reward = -114.00, steps = 115\n",
      "11:46:28 [DEBUG] test episode 36: reward = -125.00, steps = 126\n",
      "11:46:28 [DEBUG] test episode 37: reward = -123.00, steps = 124\n",
      "11:46:28 [DEBUG] test episode 38: reward = -102.00, steps = 103\n",
      "11:46:29 [DEBUG] test episode 39: reward = -119.00, steps = 120\n",
      "11:46:29 [DEBUG] test episode 40: reward = -114.00, steps = 115\n",
      "11:46:29 [DEBUG] test episode 41: reward = -127.00, steps = 128\n",
      "11:46:29 [DEBUG] test episode 42: reward = -141.00, steps = 142\n",
      "11:46:29 [DEBUG] test episode 43: reward = -109.00, steps = 110\n",
      "11:46:29 [DEBUG] test episode 44: reward = -93.00, steps = 94\n",
      "11:46:29 [DEBUG] test episode 45: reward = -120.00, steps = 121\n",
      "11:46:29 [DEBUG] test episode 46: reward = -151.00, steps = 152\n",
      "11:46:30 [DEBUG] test episode 47: reward = -160.00, steps = 161\n",
      "11:46:30 [DEBUG] test episode 48: reward = -167.00, steps = 168\n",
      "11:46:30 [DEBUG] test episode 49: reward = -123.00, steps = 124\n",
      "11:46:30 [DEBUG] test episode 50: reward = -122.00, steps = 123\n",
      "11:46:30 [DEBUG] test episode 51: reward = -135.00, steps = 136\n",
      "11:46:30 [DEBUG] test episode 52: reward = -140.00, steps = 141\n",
      "11:46:30 [DEBUG] test episode 53: reward = -145.00, steps = 146\n",
      "11:46:30 [DEBUG] test episode 54: reward = -155.00, steps = 156\n",
      "11:46:30 [DEBUG] test episode 55: reward = -110.00, steps = 111\n",
      "11:46:31 [DEBUG] test episode 56: reward = -156.00, steps = 157\n",
      "11:46:31 [DEBUG] test episode 57: reward = -140.00, steps = 141\n",
      "11:46:31 [DEBUG] test episode 58: reward = -125.00, steps = 126\n",
      "11:46:31 [DEBUG] test episode 59: reward = -102.00, steps = 103\n",
      "11:46:31 [DEBUG] test episode 60: reward = -119.00, steps = 120\n",
      "11:46:31 [DEBUG] test episode 61: reward = -127.00, steps = 128\n",
      "11:46:31 [DEBUG] test episode 62: reward = -107.00, steps = 108\n",
      "11:46:31 [DEBUG] test episode 63: reward = -146.00, steps = 147\n",
      "11:46:32 [DEBUG] test episode 64: reward = -187.00, steps = 188\n",
      "11:46:32 [DEBUG] test episode 65: reward = -101.00, steps = 102\n",
      "11:46:32 [DEBUG] test episode 66: reward = -115.00, steps = 116\n",
      "11:46:32 [DEBUG] test episode 67: reward = -159.00, steps = 160\n",
      "11:46:32 [DEBUG] test episode 68: reward = -122.00, steps = 123\n",
      "11:46:32 [DEBUG] test episode 69: reward = -122.00, steps = 123\n",
      "11:46:32 [DEBUG] test episode 70: reward = -103.00, steps = 104\n",
      "11:46:32 [DEBUG] test episode 71: reward = -126.00, steps = 127\n",
      "11:46:32 [DEBUG] test episode 72: reward = -170.00, steps = 171\n",
      "11:46:33 [DEBUG] test episode 73: reward = -119.00, steps = 120\n",
      "11:46:33 [DEBUG] test episode 74: reward = -139.00, steps = 140\n",
      "11:46:33 [DEBUG] test episode 75: reward = -126.00, steps = 127\n",
      "11:46:33 [DEBUG] test episode 76: reward = -115.00, steps = 116\n",
      "11:46:33 [DEBUG] test episode 77: reward = -141.00, steps = 142\n",
      "11:46:33 [DEBUG] test episode 78: reward = -142.00, steps = 143\n",
      "11:46:33 [DEBUG] test episode 79: reward = -124.00, steps = 125\n",
      "11:46:33 [DEBUG] test episode 80: reward = -175.00, steps = 176\n",
      "11:46:34 [DEBUG] test episode 81: reward = -113.00, steps = 114\n",
      "11:46:34 [DEBUG] test episode 82: reward = -107.00, steps = 108\n",
      "11:46:34 [DEBUG] test episode 83: reward = -119.00, steps = 120\n",
      "11:46:34 [DEBUG] test episode 84: reward = -110.00, steps = 111\n",
      "11:46:34 [DEBUG] test episode 85: reward = -123.00, steps = 124\n",
      "11:46:34 [DEBUG] test episode 86: reward = -112.00, steps = 113\n",
      "11:46:34 [DEBUG] test episode 87: reward = -166.00, steps = 167\n",
      "11:46:34 [DEBUG] test episode 88: reward = -196.00, steps = 197\n",
      "11:46:34 [DEBUG] test episode 89: reward = -134.00, steps = 135\n",
      "11:46:35 [DEBUG] test episode 90: reward = -138.00, steps = 139\n",
      "11:46:35 [DEBUG] test episode 91: reward = -120.00, steps = 121\n",
      "11:46:35 [DEBUG] test episode 92: reward = -136.00, steps = 137\n",
      "11:46:35 [DEBUG] test episode 93: reward = -114.00, steps = 115\n",
      "11:46:35 [DEBUG] test episode 94: reward = -121.00, steps = 122\n",
      "11:46:35 [DEBUG] test episode 95: reward = -119.00, steps = 120\n",
      "11:46:35 [DEBUG] test episode 96: reward = -114.00, steps = 115\n",
      "11:46:35 [DEBUG] test episode 97: reward = -118.00, steps = 119\n",
      "11:46:35 [DEBUG] test episode 98: reward = -117.00, steps = 118\n",
      "11:46:35 [DEBUG] test episode 99: reward = -126.00, steps = 127\n",
      "11:46:35 [INFO] average episode reward = -128.69 ± 21.15\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def play_episode(env, agent, max_episode_steps=None, mode=None, render=False):\n",
    "    observation, reward, done = env.reset(), 0., False\n",
    "    agent.reset(mode=mode)\n",
    "    episode_reward, elapsed_steps = 0., 0\n",
    "    while True:\n",
    "        action = agent.step(observation, reward, done)\n",
    "        if render:\n",
    "            env.render()\n",
    "        if done:\n",
    "            break\n",
    "        observation, reward, done, _ = env.step(action)\n",
    "        episode_reward += reward\n",
    "        elapsed_steps += 1\n",
    "        if max_episode_steps and elapsed_steps >= max_episode_steps:\n",
    "            break\n",
    "    agent.close()\n",
    "    return episode_reward, elapsed_steps\n",
    "\n",
    "\n",
    "logging.info('==== train ====')\n",
    "episode_rewards = []\n",
    "for episode in itertools.count():\n",
    "    episode_reward, elapsed_steps = play_episode(env.unwrapped, agent,\n",
    "            max_episode_steps=env._max_episode_steps, mode='train')\n",
    "    episode_rewards.append(episode_reward)\n",
    "    logging.debug('train episode %d: reward = %.2f, steps = %d',\n",
    "            episode, episode_reward, elapsed_steps)\n",
    "    if np.mean(episode_rewards[-10:]) > -120:\n",
    "        break\n",
    "plt.plot(episode_rewards)\n",
    "\n",
    "\n",
    "logging.info('==== test ====')\n",
    "episode_rewards = []\n",
    "for episode in range(100):\n",
    "    episode_reward, elapsed_steps = play_episode(env, agent)\n",
    "    episode_rewards.append(episode_reward)\n",
    "    logging.debug('test episode %d: reward = %.2f, steps = %d',\n",
    "            episode, episode_reward, elapsed_steps)\n",
    "logging.info('average episode reward = %.2f ± %.2f',\n",
    "        np.mean(episode_rewards), np.std(episode_rewards))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "env.close()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
